-
Notifications
You must be signed in to change notification settings - Fork 160
feat: show consents before import modal #6770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: show consents before import modal #6770
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds geo-based blocking and consent gating for token lists and imports: new restricted-lists state and persistence, list/token blocking hooks and updaters, RWA consent modal wiring, UI warnings/disabled imports, and new translation strings. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as SelectTokenWidget / ImportModal
participant Geo as GeoStatus
participant Lists as RestrictedLists / BlockedSources
participant RWA as RwaConsentModal
participant Importer as Import Hook
User->>UI: attempt import (token or list)
UI->>Geo: read geoStatus
UI->>Lists: query restricted info & blocked sources
Lists-->>UI: isBlocked / blockReason / requiresConsent
alt blocked by geo
UI->>User: show blocked warning (import disabled)
else not blocked
User->>UI: confirm import
UI->>Importer: start import flow
Importer->>Lists: check requiresConsent / consent cache
alt consent required & not cached
Importer->>RWA: open consent modal
User->>RWA: accept consent
RWA-->>Importer: onImportSuccess
Importer->>UI: proceed with import
else consent present or not required
Importer->>UI: proceed with import
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
@apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts:
- Around line 38-41: The current branch in useConsentAwareToggleList uses if
(!enabled) to skip consent, but enabled represents the current state so skipping
should occur when enabled === true (user is disabling); change the condition to
if (enabled) { baseToggleList(list, enabled); return } so that disabling skips
consent and enabling (enabled === false) proceeds to run the consent checks for
restricted lists; ensure references to baseToggleList(list, enabled), the
enabled parameter, and any restricted-list checks remain consistent with this
inverted condition.
- Line 45: The condition in useConsentAwareToggleList checks for
!geoStatus.country && restrictedLists.isLoaded but misses geoStatus.isLoading,
causing consent logic to run while geo is still fetching; update that
conditional (the one referencing geoStatus.country and restrictedLists.isLoaded
inside useConsentAwareToggleList) to also require !geoStatus.isLoading so
consent checks are deferred until geoStatus has finished loading.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.tsapps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
📚 Learning: 2025-12-30T18:49:03.377Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.tsapps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx
📚 Learning: 2025-12-30T18:51:02.867Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts:38-78
Timestamp: 2025-12-30T18:51:02.867Z
Learning: In useConsentAwareToggleList.ts and other similar toggle functions under apps/cowswap-frontend/src/modules/tokensList/hooks, clarify that the 'enabled' parameter represents the current state of the item (not the desired state). When enabled is true, the user is attempting to disable the currently-enabled item; when enabled is false, the user is attempting to enable a currently-disabled item. Ensure the toggle logic uses this current-state semantics (e.g., derive nextState as !enabled) and update comments/tests accordingly to reflect this behavior.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
📚 Learning: 2025-10-13T19:41:31.440Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6351
File: apps/cowswap-frontend/src/modules/erc20Approve/containers/TradeApproveModal/useTradeApproveCallback.ts:87-121
Timestamp: 2025-10-13T19:41:31.440Z
Learning: In apps/cowswap-frontend/src/modules/erc20Approve, useApproveCallback returns Promise<TransactionResponse | undefined> and is distinct from useApproveCurrency, which can return Promise<TransactionReceipt | SafeMultisigTransactionResponse>. When reviewing approval flows, verify which hook is actually being used before flagging Safe wallet concerns.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
📚 Learning: 2025-08-12T05:57:08.021Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6138
File: libs/hook-dapp-lib/src/hookDappsRegistry.ts:1-1
Timestamp: 2025-08-12T05:57:08.021Z
Learning: The matchHooksToDapps function in libs/hook-dapp-lib/src/utils.ts provides backward compatibility for permit hooks through function selector detection (EIP_2612_PERMIT_SELECTOR and DAI_PERMIT_SELECTOR) rather than dappId matching, making it robust against dappId changes.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
📚 Learning: 2025-10-10T20:28:16.565Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6347
File: apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx:49-49
Timestamp: 2025-10-10T20:28:16.565Z
Learning: In apps/cowswap-frontend/src/modules/trade, TradeConfirmation follows a two-layer architecture: TradeConfirmationView (pure/stateless) in pure/TradeConfirmation/index.tsx renders the UI, while TradeConfirmation (container) in containers/TradeConfirmation/index.tsx wraps it to freeze props during pending trades (via useStableTradeConfirmationProps), wire in signing state (useSigningStep), and inject trade confirmation state (useTradeConfirmState). Consuming modules should import the container TradeConfirmation from 'modules/trade' to preserve this stateful behavior.
<!-- [add_learning]
When reviewing component refactoring in apps/cowswap-frontend/src/modules/trade, recognize the pattern where a pure view component (e.g., TradeConfirmationView) is separated from a stateful container (e.g., TradeConfirmation) that wraps it. The container adds runtime state management (prop stabilization, signing state, etc.) while the view remains testable and composable. Do not flag usages that import th...
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
📚 Learning: 2025-08-08T13:55:17.528Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6125
File: libs/tokens/src/state/tokens/allTokensAtom.ts:78-78
Timestamp: 2025-08-08T13:55:17.528Z
Learning: In libs/tokens/src/state/tokens/allTokensAtom.ts (TypeScript/Jotai), the team prefers to wait for token lists to initialize (listsStatesListAtom non-empty) before returning tokens. No fallback to favorites/user-added/native tokens should be used when listsStatesList is empty.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
📚 Learning: 2025-12-30T18:51:07.806Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts:38-78
Timestamp: 2025-12-30T18:51:07.806Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts and similar toggle functions, the `enabled` parameter represents the current state of the item (not the desired state). When `enabled === true`, the item is currently enabled and the user is disabling it; when `enabled === false`, the item is currently disabled and the user is enabling it.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx
📚 Learning: 2025-08-08T13:56:18.009Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6125
File: libs/tokens/src/updaters/TokensListsUpdater/index.tsx:29-31
Timestamp: 2025-08-08T13:56:18.009Z
Learning: In libs/tokens/src/updaters/TokensListsUpdater/index.tsx, the project’s current Jotai version requires using `unstable_getOnInit` (not `getOnInit`) in atomWithStorage options; keep `{ unstable_getOnInit: true }` until Jotai is upgraded.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx
📚 Learning: 2025-09-19T11:38:59.206Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6232
File: apps/cowswap-frontend/src/modules/tokensList/pure/ChainsSelector/index.tsx:199-200
Timestamp: 2025-09-19T11:38:59.206Z
Learning: The makeBuildClickEvent function in apps/cowswap-frontend/src/modules/tokensList/pure/ChainsSelector/index.tsx takes five parameters: defaultChainId, contextLabel, mode, isSwapMode, and chainsCount. The chainsCount parameter is used to determine the CrossChain flag in analytics events.
Applied to files:
apps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx
🧬 Code graph analysis (1)
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts (7)
libs/tokens/src/types.ts (1)
ListState(39-42)apps/cowswap-frontend/src/modules/rwa/hooks/useGeoStatus.ts (1)
useGeoStatus(10-19)libs/tokens/src/index.ts (2)
restrictedListsAtom(60-60)getSourceAsKey(79-79)apps/cowswap-frontend/src/modules/rwa/state/rwaConsentAtom.ts (1)
rwaConsentCacheAtom(8-10)apps/cowswap-frontend/src/modules/rwa/hooks/useRwaConsentModalState.ts (1)
useRwaConsentModalState(13-48)libs/tokens/src/hooks/lists/useIsListBlocked.ts (1)
getSourceAsKey(6-8)apps/cowswap-frontend/src/modules/rwa/types/rwaConsent.ts (1)
RwaConsentKey(11-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Cypress
- GitHub Check: Setup
🔇 Additional comments (2)
apps/cowswap-frontend/src/modules/tokensList/pure/ListItem/index.tsx (2)
36-39: LGTM: Good state synchronization pattern.The useEffect ensures
isActivestays in sync with the parent'senabledprop while allowing immediate UI feedback on toggle. The comment clearly documents this intent.
41-50: The code is correct and consistent.The
enabledparameter represents the desired state (not current state as suggested by the learning). ListItem correctly computesnewState = !enabledand passes it totoggleList, where it's used for consent checks and analytics. The actual toggle is performed internally bytoggleListAtom, which inverts the current state. All callers and the consent modal logic are consistent with this pattern.
apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
Show resolved
Hide resolved
|
|
||
| // trying to enable - check if consent is required | ||
| // only require consent when country is unknown (blocked countries are handled by hiding the list) | ||
| if (!geoStatus.country && restrictedLists.isLoaded) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add isLoading check to defer consent during geo fetch.
The condition checks !geoStatus.country && restrictedLists.isLoaded but doesn't verify !geoStatus.isLoading. When geo data is still loading, country is typically undefined, so the code enters the consent-checking block prematurely. According to retrieved learnings, when geoStatus.isLoading is true, imports should proceed without blocking to defer consent checks to trade time.
🔧 Proposed fix
- if (!geoStatus.country && restrictedLists.isLoaded) {
+ if (!geoStatus.country && !geoStatus.isLoading && restrictedLists.isLoaded) {
const sourceKey = getSourceAsKey(list.source)
const consentHash = restrictedLists.consentHashPerList[sourceKey]Based on learnings, deferring consent checks when geo status is loading ensures that toggles proceed smoothly and consent verification occurs only when necessary data is available.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!geoStatus.country && restrictedLists.isLoaded) { | |
| if (!geoStatus.country && !geoStatus.isLoading && restrictedLists.isLoaded) { | |
| const sourceKey = getSourceAsKey(list.source) | |
| const consentHash = restrictedLists.consentHashPerList[sourceKey] |
🤖 Prompt for AI Agents
In
@apps/cowswap-frontend/src/modules/tokensList/hooks/useConsentAwareToggleList.ts
at line 45, The condition in useConsentAwareToggleList checks for
!geoStatus.country && restrictedLists.isLoaded but misses geoStatus.isLoading,
causing consent logic to run while geo is still fetching; update that
conditional (the one referencing geoStatus.country and restrictedLists.isLoaded
inside useConsentAwareToggleList) to also require !geoStatus.isLoading so
consent checks are deferred until geoStatus has finished loading.
|
@elena-zh thank for testing, good catch, I've added check for this case, could u pls check it again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx (1)
66-73: Combine duplicate hook calls into a single destructuring.
useRwaConsentModalState()is called twice (lines 66 and 73) to destructure different properties. This is inefficient and could potentially cause issues if the hook manages local state rather than context. Consolidate into a single call.♻️ Combine the two calls into one
- const { isModalOpen: isRwaConsentModalOpen, closeModal: closeRwaConsentModal } = useRwaConsentModalState() const { tokensToImport, modalState: { isModalOpen: isAutoImportModalOpen, closeModal: closeAutoImportModal }, } = useAutoImportTokensState(rawState?.inputCurrencyId, rawState?.outputCurrencyId) const { isImportDisabled, blockReason, requiresConsent, restrictedTokenInfo, tokenNeedingConsent } = useRestrictedTokensImportStatus(tokensToImport) - const { openModal: openRwaConsentModal } = useRwaConsentModalState() + const { isModalOpen: isRwaConsentModalOpen, closeModal: closeRwaConsentModal, openModal: openRwaConsentModal } = + useRwaConsentModalState()
🧹 Nitpick comments (1)
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx (1)
126-156: Consider adding a guard to prevent reopening the consent modal.The effect correctly opens the consent modal when conditions are met. However, adding
isRwaConsentModalOpento the dependencies with a guard condition would make the intent more explicit and prevent potential race conditions if the modal state update is delayed.♻️ Add guard condition
useEffect(() => { - if (isAutoImportModalOpen && requiresConsent && restrictedTokenInfo && tokenNeedingConsent) { + if (!isRwaConsentModalOpen && isAutoImportModalOpen && requiresConsent && restrictedTokenInfo && tokenNeedingConsent) { openRwaConsentModal({ consentHash: restrictedTokenInfo.consentHash, token: tokenNeedingConsent, pendingImportTokens: tokensToImport, onImportSuccess: () => { // After consent, import the tokens importTokenCallback(tokensToImport) closeAutoImportModal() }, onDismiss: () => { // If consent is rejected, close the auto-import modal too closeAutoImportModal() }, }) } }, [ + isRwaConsentModalOpen, isAutoImportModalOpen, requiresConsent, restrictedTokenInfo, tokenNeedingConsent, tokensToImport, openRwaConsentModal, importTokenCallback, closeAutoImportModal, ])
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/cowswap-frontend/src/modules/rwa/containers/RwaConsentModalContainer/index.tsxapps/cowswap-frontend/src/modules/rwa/state/rwaConsentModalStateAtom.tsapps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/cowswap-frontend/src/modules/rwa/containers/RwaConsentModalContainer/index.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
📚 Learning: 2025-12-30T18:49:03.377Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
Applied to files:
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsxapps/cowswap-frontend/src/modules/rwa/state/rwaConsentModalStateAtom.ts
📚 Learning: 2025-10-10T20:28:16.565Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6347
File: apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx:49-49
Timestamp: 2025-10-10T20:28:16.565Z
Learning: In apps/cowswap-frontend/src/modules/trade, TradeConfirmation follows a two-layer architecture: TradeConfirmationView (pure/stateless) in pure/TradeConfirmation/index.tsx renders the UI, while TradeConfirmation (container) in containers/TradeConfirmation/index.tsx wraps it to freeze props during pending trades (via useStableTradeConfirmationProps), wire in signing state (useSigningStep), and inject trade confirmation state (useTradeConfirmState). Consuming modules should import the container TradeConfirmation from 'modules/trade' to preserve this stateful behavior.
<!-- [add_learning]
When reviewing component refactoring in apps/cowswap-frontend/src/modules/trade, recognize the pattern where a pure view component (e.g., TradeConfirmationView) is separated from a stateful container (e.g., TradeConfirmation) that wraps it. The container adds runtime state management (prop stabilization, signing state, etc.) while the view remains testable and composable. Do not flag usages that import th...
Applied to files:
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsxapps/cowswap-frontend/src/modules/rwa/state/rwaConsentModalStateAtom.ts
📚 Learning: 2025-07-24T16:42:53.154Z
Learnt from: cowdan
Repo: cowprotocol/cowswap PR: 6009
File: apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx:23-33
Timestamp: 2025-07-24T16:42:53.154Z
Learning: In apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx, the use of toFixed(2) for percentage formatting in tooltip content is intentional and differs from the banner message formatting that uses toSignificant(2, undefined, Rounding.ROUND_DOWN). This formatting difference serves different UX purposes and should not be flagged as inconsistent.
Applied to files:
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx
📚 Learning: 2025-08-08T13:55:17.528Z
Learnt from: shoom3301
Repo: cowprotocol/cowswap PR: 6125
File: libs/tokens/src/state/tokens/allTokensAtom.ts:78-78
Timestamp: 2025-08-08T13:55:17.528Z
Learning: In libs/tokens/src/state/tokens/allTokensAtom.ts (TypeScript/Jotai), the team prefers to wait for token lists to initialize (listsStatesListAtom non-empty) before returning tokens. No fallback to favorites/user-added/native tokens should be used when listsStatesList is empty.
Applied to files:
apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx
🧬 Code graph analysis (1)
apps/cowswap-frontend/src/modules/rwa/state/rwaConsentModalStateAtom.ts (1)
libs/common-const/src/types.ts (1)
TokenWithLogo(6-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Lint
- GitHub Check: Build
- GitHub Check: Test
- GitHub Check: Cypress
🔇 Additional comments (2)
apps/cowswap-frontend/src/modules/rwa/state/rwaConsentModalStateAtom.ts (1)
6-21: LGTM! Well-structured modal state interface.The
RwaConsentModalContextinterface cleanly supports both single-token (token?) and multi-token (pendingImportTokens?) import flows with appropriate lifecycle callbacks. Type safety is maintained, and the design aligns well with the PR's requirements for handling individual token and token list imports.apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetModals.tsx (1)
178-189: LGTM! Consent gating integrated correctly.The conditional rendering correctly separates the consent flow from the standard import flow. When consent is required, the
useEffectabove handles opening the consent modal. When consent is not required but import is disabled (blocked country), the modal displays with a disabled state and block reason. This approach maintains clear separation of concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @apps/cowswap-frontend/src/locales/en-US.po:
- Around line 3601-3602: The PO entry contains a leftover merge conflict marker
in the translation string for the "With hooks you can add specific actions
<0>before</0> and <1>after</1> your swap." message; remove the conflict marker
text ("<<<<<<< Updated upstream") from the msgstr so the translated string is a
valid PO value (no conflict markers, correct escaping/markup preserved) and save
the file.
🧹 Nitpick comments (1)
apps/cowswap-frontend/src/locales/en-US.po (1)
3603-3607: Potential duplication: “This token is not available in your region.” vs existing msgid without period.
This file already containsmsgid "This token is not available in your region"(no trailing.). Consider standardizing to one msgid to avoid near-duplicate strings (and inconsistent punctuation across UI).
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/cowswap-frontend/src/locales/en-US.po
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
📚 Learning: 2025-12-30T18:49:03.377Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6770
File: apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts:27-31
Timestamp: 2025-12-30T18:49:03.377Z
Learning: In apps/cowswap-frontend/src/modules/tokensList/hooks/useAddListImport.ts, when restrictedLists.isLoaded is false or geoStatus.isLoading is true, the code intentionally proceeds with the import immediately without blocking. This allows imports to proceed during loading states, deferring consent checks to trade time when necessary data isn't yet available.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-07-18T08:07:55.497Z
Learnt from: alfetopito
Repo: cowprotocol/cowswap PR: 5992
File: libs/tokens/src/const/tokensList.json:135-167
Timestamp: 2025-07-18T08:07:55.497Z
Learning: Token lists for CoW Swap are maintained in a separate repository at https://github.com/cowprotocol/token-lists, not in the main cowswap repository. Issues related to missing token lists should be tracked in the token-lists repository.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-07-24T16:42:53.154Z
Learnt from: cowdan
Repo: cowprotocol/cowswap PR: 6009
File: apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx:23-33
Timestamp: 2025-07-24T16:42:53.154Z
Learning: In apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/HighFeeWarningTooltipContent.tsx, the use of toFixed(2) for percentage formatting in tooltip content is intentional and differs from the banner message formatting that uses toSignificant(2, undefined, Rounding.ROUND_DOWN). This formatting difference serves different UX purposes and should not be flagged as inconsistent.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-05-28T16:50:12.273Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 5768
File: apps/cow-fi/components/LearnPageComponent.tsx:184-185
Timestamp: 2025-05-28T16:50:12.273Z
Learning: In apps/cow-fi/components/LearnPageComponent.tsx, the user prefers to keep the inconsistent link behavior where featured articles always open in new tabs (target="_blank") while media coverage links conditionally open in new tabs based on the linkExternal flag. This inconsistency should not be flagged as an issue in future reviews.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-10-13T19:41:31.440Z
Learnt from: limitofzero
Repo: cowprotocol/cowswap PR: 6351
File: apps/cowswap-frontend/src/modules/erc20Approve/containers/TradeApproveModal/useTradeApproveCallback.ts:87-121
Timestamp: 2025-10-13T19:41:31.440Z
Learning: In apps/cowswap-frontend/src/modules/erc20Approve, useApproveCallback returns Promise<TransactionResponse | undefined> and is distinct from useApproveCurrency, which can return Promise<TransactionReceipt | SafeMultisigTransactionResponse>. When reviewing approval flows, verify which hook is actually being used before flagging Safe wallet concerns.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-10-10T20:28:16.565Z
Learnt from: fairlighteth
Repo: cowprotocol/cowswap PR: 6347
File: apps/cowswap-frontend/src/modules/trade/pure/TradeConfirmation/index.tsx:49-49
Timestamp: 2025-10-10T20:28:16.565Z
Learning: In apps/cowswap-frontend/src/modules/trade, TradeConfirmation follows a two-layer architecture: TradeConfirmationView (pure/stateless) in pure/TradeConfirmation/index.tsx renders the UI, while TradeConfirmation (container) in containers/TradeConfirmation/index.tsx wraps it to freeze props during pending trades (via useStableTradeConfirmationProps), wire in signing state (useSigningStep), and inject trade confirmation state (useTradeConfirmState). Consuming modules should import the container TradeConfirmation from 'modules/trade' to preserve this stateful behavior.
<!-- [add_learning]
When reviewing component refactoring in apps/cowswap-frontend/src/modules/trade, recognize the pattern where a pure view component (e.g., TradeConfirmationView) is separated from a stateful container (e.g., TradeConfirmation) that wraps it. The container adds runtime state management (prop stabilization, signing state, etc.) while the view remains testable and composable. Do not flag usages that import th...
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
📚 Learning: 2025-07-24T16:43:47.639Z
Learnt from: cowdan
Repo: cowprotocol/cowswap PR: 6009
File: apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/highFeeWarningHelpers.ts:18-20
Timestamp: 2025-07-24T16:43:47.639Z
Learning: In apps/cowswap-frontend/src/modules/tradeWidgetAddons/containers/HighFeeWarning/highFeeWarningHelpers.ts, the formatFeePercentage function uses ROUND_DOWN with toSignificant(2) for "at least X%" messaging. This ensures the displayed percentage is never higher than the actual fee, making the "at least" phrasing accurate. For example, if the actual fee is 25.4%, displaying "at least 25%" is correct, but "at least 26%" would be misleading.
Applied to files:
apps/cowswap-frontend/src/locales/en-US.po
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Setup
- GitHub Check: Cypress
🔇 Additional comments (3)
apps/cowswap-frontend/src/locales/en-US.po (3)
2822-2825: Good addition: clear blocked-list message.
Translation entry looks fine and matches the intended UX.
3636-3639: Good: concise label for blocked lists/items.
Looks appropriate for compact UI surfaces.
4321-4324: Good: consent gating copy is clear.
String reads well for a pre-import warning/notice.
| msgstr "With hooks you can add specific actions <0>before</0> and <1>after</1> your swap.<<<<<<< Updated upstream" | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocker: unresolved merge conflict marker in PO file.
<<<<<<< Updated upstream in msgstr will likely break localization extraction/compilation and must be removed.
Proposed fix
-msgstr "With hooks you can add specific actions <0>before</0> and <1>after</1> your swap.<<<<<<< Updated upstream"
+msgstr "With hooks you can add specific actions <0>before</0> and <1>after</1> your swap."📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| msgstr "With hooks you can add specific actions <0>before</0> and <1>after</1> your swap.<<<<<<< Updated upstream" | |
| msgstr "With hooks you can add specific actions <0>before</0> and <1>after</1> your swap." |
🤖 Prompt for AI Agents
In @apps/cowswap-frontend/src/locales/en-US.po around lines 3601 - 3602, The PO
entry contains a leftover merge conflict marker in the translation string for
the "With hooks you can add specific actions <0>before</0> and <1>after</1> your
swap." message; remove the conflict marker text ("<<<<<<< Updated upstream")
from the msgstr so the translated string is a valid PO value (no conflict
markers, correct escaping/markup preserved) and save the file.
|
Hey @limitofzero , great! The flow is working fine. |
Summary
This PR extends the RWA (Real World Assets) consent system to cover token importing flows, in addition to the existing trading flows. It blocks users from importing restricted tokens or token lists when they are in a blocked country.
Resolves this issue.
Key Changes
1. Block Token List Imports for Blocked Countries
2. Block Individual Token Imports for Blocked Countries
3. Hide Blocked Token Lists from UI
4. Consent Flow for Unknown Countries (Wallet Connected)
5. No Blocking for Unknown Countries (No Wallet)
modal with consents for token list

Testing table
To Test
Test restricted token import from blocked country:
Test token list import from blocked country:
Test Manage Lists filtering:
Test import with unknown country + wallet connected:
Test import with unknown country + no wallet:
Summary by CodeRabbit
New Features
UI
Localization
Tests
✏️ Tip: You can customize this high-level summary in your review settings.